
package ReadWGZ;
import java.io.ObjectInputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import java.util.zip.GZIPInputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.util.List;

import util.GAConfig;

import model.TestClusterBuilder;
import instrumentation.*;
public class ReadFilewgzMDR{
//	private Map<String, BlockClass> blckClasses= new HashMap<String, BlockClass>();
//	private Map<String,Set<Integer>> mapBranchCondition= new HashMap<String, Set<Integer>>();
	public  final Map<String, BlockClass>  readFileWGZ(List<TestClusterBuilder> TestClusterList)throws  IOException, ClassNotFoundException{
		  Map<String, BlockClass> blckClasses= new HashMap<String, BlockClass>();
		for(TestClusterBuilder tCluster:TestClusterList){
		Map<String,Class<?>> classesToTest=tCluster.getClassToTest();
		
		ReadFilewgzMDR readFile = new ReadFilewgzMDR();
		for (String cName : classesToTest.keySet()) {
			Class<?> clazz=(Class<?>) classesToTest.get(cName);
			String classFileName=clazz.getName();

			classFileName=classFileName.replace('.', '/');
			classFileName=classFileName+".wgz";
			String inst=GAConfig.getDirInstrumented().toString();
			inst=inst.replace('\\', '/')+"/";
			// classFileName="file:"+inst+classFileName.toString();
			 String classFileName_="file:./instrumented/"+classFileName.toString();
			 blckClasses.putAll(readFile.getClassBlock(classFileName_));
			//mapBranchCondition.putAll( readFile(clazzes));
		}
		  }
		return  blckClasses;
	}
	public  Map<String, BlockClass>  getClassBlock(String cName) throws  IOException, ClassNotFoundException {
		 Map<String, BlockClass> blckClasses= new HashMap<String, BlockClass>();
		try {
			ObjectInput oi = new ObjectInputStream(new GZIPInputStream(new URL(cName).openStream()));
			BlockClass bClass = (BlockClass) oi.readObject();
			if(blckClasses.containsKey(bClass.getClzName())) return blckClasses;
			blckClasses.put(bClass.getClzName(), bClass);
		} catch (Throwable e) {
			System.err.println("ReadFilewgz.read: " + e);
			System.exit(1);
		}
		return blckClasses;	
	}
public  Map<String,Set<Integer>> getClazzCondition(Map<String, BlockClass> blckClasses){
	Map<String,Set<Integer>> mapBranchCondition= new HashMap<String, Set<Integer>>();
			for (Entry<String, BlockClass> block : blckClasses.entrySet()) {
			// if(mapBranchCondition.containsKey(bClass.getClzName())) return
			// mapBranchCondition.get(bClass.getClzName());
			BlockClass blckClazz = block.getValue();
			Set<Integer> condition = new HashSet<Integer>();
			Set<BlockMethodEntry> blckMethd = blckClazz.getBlockMethods();
			for (BlockMethodEntry b : blckMethd) {
				Set<Condition> conditions = b.getCondition();

				for (Condition c : conditions)
					if(c instanceof ConditionIf )
						condition.add(c.getBranchId());
					else{
						ConditionSwitch cSwitch=(ConditionSwitch) c;
						Map<Integer,Integer> cases=cSwitch.getCases();
						condition.addAll(cases.keySet());
						condition.add(cSwitch.getDefaultCase());
						}

			}
			mapBranchCondition.put(blckClazz.getClzName(), condition);
		}
			return mapBranchCondition;
}
	public void displayBlock(Map<String, BlockClass> blckClasses){
		for (Map.Entry<String, BlockClass> entry : blckClasses.entrySet()) { 
			System.out.print(entry.getValue().toString());
		}
	}
  public  static void main(String[] args) {
			try {
				ReadFilewgzMDR m = new ReadFilewgzMDR();
				Map<String, BlockClass> blckClasses= new HashMap<String, BlockClass>();
				 Set<Class<?>> allClasses = new LinkedHashSet<Class<?>>();
			      //get class from file
			      allClasses.addAll(TestClusterBuilder.readClassFromFile());
			      System.out.println("There are " + allClasses.size() + " classes as input");
			      System.out.println(allClasses);
			//      TestClusterBuilder TestCluster = new TestClusterBuilder(allClasses);
			      List<TestClusterBuilder> TestClusterList= TestClusterBuilder.buildTestClusterList(allClasses);
			      blckClasses=m.readFileWGZ(TestClusterList);
			      	m.displayBlock(blckClasses);
//			      	Map<String,Set<Integer>> clazzBranch= m.getClazzCondition(blckClasses);
//			      	for (Entry<String,Set<Integer>> clz : clazzBranch.entrySet()) {
//			      			System.out.println( clz.getKey()+" ("+ clz.getValue().size() +")"+ clz.getValue());
//			      	}
			} catch (Throwable e) {
				System.err.println("IO error: " + e.getMessage());
				System.exit(1);
			}
			System.exit(0);
  }

}